package com.springboot.cloud.authorization.service.impl;

import com.springboot.cloud.authorization.entity.Role;
import com.springboot.cloud.authorization.service.RoleService;
import com.springboot.cloud.authorization.service.UserService;
import com.springboot.cloud.core.model.SystemUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Service;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>  </p>
 *
 * @author Bertram
 * @since 11/4/2019 4:39 PM
 */
@Service("customUserDetailsService")
@Slf4j
public class CustomUserDetailsServiceImpl implements UserDetailsService {

    private UserService userService;
    private RoleService roleService;

    public CustomUserDetailsServiceImpl(UserService userService, RoleService roleService) {
        this.userService = userService;
        this.roleService = roleService;
    }

    @Override
    public UserDetails loadUserByUsername(String uniqueId) {
        SystemUser user = userService.getByUniqueId(uniqueId);
        log.info("load user by username :{}", user.toString());
        return new org.springframework.security.core.userdetails.User(
                user.getUserName(),
                user.getPassword(),
                true,
                true,
                true,
                true,
                this.obtainGrantedAuthorities(user));
    }

    /**
     * 获得登录者所有角色的权限集合.
     *
     * @param user
     * @return
     */
    private Set<GrantedAuthority> obtainGrantedAuthorities(SystemUser user) {
        Set<Role> roles = roleService.queryUserRolesByUserId(user.getSystemUserId().toString());
        log.info("user:{},roles:{}", user.getUserName(), roles);
        return roles.stream().map(role -> new SimpleGrantedAuthority(role.getCode())).collect(Collectors.toSet());
    }
}
